package org.dreamwork.sso.saml2.spec;

import org.dreamwork.sso.saml2.SamlKeys;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dreamwork.misc.ResourceFinder;
import org.dreamwork.util.StringUtil;

import java.io.InputStream;
import java.util.Properties;

/**
 * Created with IntelliJ IDEA.
 * User: seth.yang
 * Date: 13-8-13
 * Time: 下午3:21
 */
public abstract class KeyFetcherFactory {

    private static KeyFetcherFactory instance;

    private static Log logger = LogFactory.getLog (KeyFetcherFactory.class);

    @SuppressWarnings ("unchecked")
    public static KeyFetcherFactory newInstance () {
        try {
            if (instance == null) {
                InputStream in = ResourceFinder.findResource (SamlKeys.CONFIG_FILE_KEY, SamlKeys.DEFAULT_CONFIG_FILE_NAME);
                if (in == null)
                    throw new IllegalArgumentException ("Can't find key fetcher config file!");

                try {
                    Properties props = new Properties ();
                    props.load (in);

                    String className = props.getProperty (SamlKeys.KEY_FETCHER_CLASSNAME);
                    if (StringUtil.isEmpty (className))
                        throw new RuntimeException ("Can't find key fetcher factory");

                    Class c = Class.forName (className.trim ());
                    Class thisClass = KeyFetcherFactory.class;
                    if (!thisClass.isAssignableFrom (c))
                        throw new ClassCastException ("Can't cast class " + c.getCanonicalName () + " to " + thisClass.getCanonicalName ());
                    Class<KeyFetcherFactory> factoryClass = (Class<KeyFetcherFactory>) c;
                    instance = factoryClass.newInstance ();
                } finally {
                    in.close ();
                }
            }
            return instance;
        } catch (Exception ex) {
            logger.warn (ex.getMessage (), ex);
            throw new RuntimeException (ex);
        }
    }

    public abstract IKeyFetcher getFetcher ();
}